cc.Class({
    extends: cc.Component,

    properties: {
        mapCamera: {
            displayName: '地图摄像机',
            type: cc.Camera,
            default: null
        },
        mapNode: {
            displayName: '地图节点',
            type: cc.Node,
            default: null
        },
        childParent: {
            displayName: '地图节点父类',
            type: cc.Node,
            default: null
        }
    },

    // use this for initialization
    onLoad: function () {
        this.node.on(cc.Node.EventType.MOUSE_WHEEL, this.onMouseWheel, this);
        //点击事件
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        //点击事件
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchBegan, this);
        //
        this.loadMap();
        this.initObjects();
    },

    start() {
        this.checkView();
    },

    initObjects() {
        for (let i = 0; i < 20; i++) {
            let x = (Math.random() - 0.5) * 750 * 2;
            let y = (Math.random() - 0.5) * 1334 * 2;
            let p = cc.v2(x, y);
            cc.loader.loadRes('prefabs/3DNode', cc.Prefab, (error, prefab) => {
                let node = cc.instantiate(prefab);
                node.parent = this.childParent;
                node.position = p;
            });
        }
    },

    loadMap() {
        let url = 'world/WorldMap';
        cc.loader.loadRes(url, cc.TiledMapAsset, (err, res) => {
            let mapNode = new cc.Node("map");
            // 添加【地图】组件
            let mapTiled = mapNode.addComponent(cc.TiledMap);
            mapNode.noShareVertices = true;
            // 获取【地图Url地址】
            mapNode.parent = this.mapNode;
            mapTiled.tmxAsset = res;
            this.m_tileMap = mapTiled;
        });
    },

    // called every frame
    update: function (dt) {

    },

    onMouseWheel(event) {
        let scrollY = event.getScrollY();
        this.mapCamera.node.z += scrollY;
    },

    onTouchMove(event) {
        let delta_pos = event.getDelta().mul(1);
        let cameraNode = this.mapCamera.node;
        cameraNode.position = cameraNode.position.sub(delta_pos);
        this.checkView();
    },

    onTouchBegan(event) {

    },

	//
    checkView() {
        if (!this.m_tileMap) return;
        let camera = this.mapCamera;
        //临时
        //centerP = centerP.add(cc.v2(0, 667));
        let width = cc.game.canvas.width / cc.view._scaleX;
        let height = cc.game.canvas.height / cc.view._scaleY;
        let screenRect = new cc.Rect(0, 0, width, height);
        let screenArray = [];
        screenArray.push(cc.v2(0, 0));
        screenArray.push(cc.v2(0, height));
        screenArray.push(cc.v2(width, height));
        screenArray.push(cc.v2(width, 0));
        let worldArray = [];
        screenArray.forEach((sp) => {
            let p = camera.MyScreenToWorld(sp);
            worldArray.push(p.add(cc.v2(-width / 2, -height / 2)));
        })
        let xMin = null;
        let yMin = null;
        let xMax = null;
        let yMax = null;
        worldArray.forEach((p) => {
            if (xMin === null || p.x < xMin) {
                xMin = p.x;
            }
            if (yMin === null || p.y < yMin) {
                yMin = p.y;
            }
            if (xMax === null || p.x > xMax) {
                xMax = p.x;
            }
            if (yMax === null || p.y > yMax) {
                yMax = p.y;
            }
        });
        let mapConfig = this.getMapConfigData();
        let startP = cc.v2(xMin, yMax)
            .add(cc.v2(mapConfig.size.width / 2, mapConfig.size.height / 2))
            .add(cc.v2(-mapConfig.mapTileSize.width / 2, mapConfig.mapTileSize.height / 2));
        let endP = cc.v2(xMax, yMin)
            .add(cc.v2(mapConfig.size.width / 2, mapConfig.size.height / 2))
            .add(cc.v2(mapConfig.mapTileSize.width / 2, -mapConfig.mapTileSize.height / 2));
        let x = startP.x;
        let y = startP.y;
        let maxRow = mapConfig.layerSize.height;
        let maxCol = mapConfig.layerSize.width;
        let array = [];
        let r = 0;
        while (x != null && y != null) {
            if (x > endP.x) {
                y = y - mapConfig.mapTileSize.height / 2;
                if (y < endP.y) {
                    break;
                } else {
                    r++;
                    x = startP.x + r % 2 * mapConfig.mapTileSize.width / 2;
                }
            } else {
                x = x + mapConfig.mapTileSize.width;
            }
            let p = cc.v2(x, y);
            let tileP = this.convertPosToTile(p);
            let tilex = tileP.x % maxCol;
            let tiley = tileP.y % maxRow;
            if (tilex < 0) {
                tilex += maxCol;
            }
            if (tiley < 0) {
                tiley += maxRow;
            }
            let tileData = {
                tilePos: cc.v2(tilex, tiley),
                realTilePos: tileP,
            }

            array.push(tileData);
        }

        for (let i = 0; i < mapConfig.tileLayers.length; i++) {
            let tileLayer = mapConfig.tileLayers[i];
            tileLayer.needTileArray = array;
        }

    },


    getMapConfigData() {
        let tileLayers = this.m_tileMap.getLayers();
        let mapTileSize = tileLayers[0].getMapTileSize();
        let layerSize = tileLayers[0].getLayerSize();
        let size = cc.size(layerSize.width * mapTileSize.width, layerSize.height * mapTileSize.height);
        return {
            mapTileSize: mapTileSize,
            layerSize: layerSize,
            size: size,
            tileLayers: tileLayers,
            tilelayer: tileLayers[0]
        }
    },
    convertPosToTile(p) {
        let mapConfig = this.getMapConfigData();
        let w1 = mapConfig.mapTileSize.width;
        let h1 = mapConfig.mapTileSize.height;
        let w2 = mapConfig.layerSize.width;
        let h2 = mapConfig.layerSize.height;
        let x = (p.x * 2 / w1 - w2 + 1 - (p.y * 2 / h1 + 2 - h2 * 2)) / 2;
        let y = (p.x * 2 / w1 - w2 + 1 + (p.y * 2 / h1 + 2 - h2 * 2)) / -2;
        x = Math.ceil(x);
        y = Math.ceil(y);
        return cc.v2(x, y);
    },
    //

    convertTileToPos(p) {
        let mapConfig = this.getMapConfigData();
        let pos = mapConfig.tilelayer.getPositionAt(p.x, p.y);
        return pos;
    },
});
